<?php
/**
 * Kernelius_Cache persistent and failover caching system
 * @author Fernando Palomo Garcia fernando@kernelius.com
 * @version 0.1
 * @license Apache License 2.0
 */
class Kernelius_Cache{

    protected $_memcacheCluster;
    protected $_persistent=NULL;

    const DEFAULT_EXPIRY=120;

    public function __construct($servers_config, $persistent=NULL, $persistent_config=NULL){
        if(!is_array($servers_config)){
            throw new exception("SERVERS CONFIG ERROR");
        }

        if($persistent){
            $persistent_class= "Kernelius_Cache_Persistent_".$persistent;
            $this->_persistent=new $persistent_class($persistent_config);
        }
        $this->_memcacheCluster= new Kernelius_Cache_MemcacheCluster($servers_config);
        //        var_dump($this);
    }


    /**
     * save key in cache
     * @param string $key
     * @param data $value
     * @param int $timeout
     * @return bool
     */
    public function set($key, $value, $timeout=self::DEFAULT_EXPIRY){
        Kernelius_Logger::log("set $key to cache system");
        if($this->_persistent){
            $this->_persistent->set($key,$value);
        }
        $this->_memcacheCluster->set($key,$value,$timeout);
        return true;
    }


    /**
     * retrieve key
     * @param string $key
     * @return data
     */
    public function get($key, $newExpiryDate=NULL){
        Kernelius_Logger::log("get $key from cache system");

        $value = $this->_memcacheCluster->get($key,$newExpiryDate);
        
        if($value){
            $this->_persistent->touch($key);
        }else if($this->_persistent){
            $value= $this->_persistent->get($key);
            if($value){
                $this->_memcacheCluster->set($key,$value,$newExpiryDate);
            }
        }
        Kernelius_Logger::log("$key => $value");
        return $value;
    }


    /**
     * delete one key from cache servers
     * @param string $key to delete
     */
    public function delete($key){
        if($this->_persistent){
            $this->_persistent->delete($key);
        }
        $this->_memcacheCluster->delete($key);
    }


    /**
     * touch key, refresh expiry
     * @param key $key
     * @param int $newExpiryDate
     * @return Kernelius_Cache
     */
    public function touch($key, $newExpiryDate=NULL){
        if(!$newExpiryDate){
            $newExpiryDate=self::DEFAULT_EXPIRY;
        }
        $this->_memcacheCluster->set($key,$this->_memcacheCluster->get($key),$newExpiryDate);
        return $this;
    }


    /**
     * remove old sessions
     * @param <type> $older
     */
    public function gc($older){
        if($this->_persistent){
            $this->_persistent->gc($older);
        }
    }

}